package com.effect.GOP.singleton;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

/**
 * * Created by Administrator on 2017/1/3.
 * 单例模式学习
 * 1.静态实例，带有static关键字的属性在每一个类中都是唯一的。
 * <p>
 * 2.限制客户端随意创造实例，即私有化构造方法，此为保证单例的最重要的一步。
 * <p>
 * 3.给一个公共的获取实例的静态方法，注意，是静态的方法，因为这个方法是在我们未获取到实例的时候就要提供给客户端调用的，所以如果是非静态的话，那就变成一个矛盾体了，因为非静态的方法必须要拥有实例才可以调用。
 * <p>
 * 4.判断只有持有的静态实例为null时才调用构造方法创造一个实例，否则就直接返回。
 * <p>
 * http://www.cnblogs.com/zuoxiaolong/p/pattern2.html
 */
public class SingletonLearn {

    public static void main(String[] args) throws InterruptedException {
        final Set<String> instanceSet = Collections.synchronizedSet(new HashSet<String>());
        ExecutorService executorService = Executors.newCachedThreadPool();
        for (int i = 0; i < 10000; i++) {
            executorService.execute(new Runnable() {

                public void run() {
                    Singleton singleton = Singleton.getInstance();
                    instanceSet.add(singleton.toString());
                }
            });
        }
        TimeUnit.SECONDS.sleep(10);
        System.out.println("------并发情况下我们取到的实例------");
        for (String instance : instanceSet) {
            System.out.println(instance);
        }
        executorService.shutdownNow();
    }
}


class Singleton {
    //一个静态的实例
    private static Singleton singleton;

    //私有化构造函数
    public Singleton() {
    }

    public static Singleton getInstance() {
        if (singleton == null) {
            Thread.yield();            //创造多个实例的条件：第一个线程走到这让步，第二个线程走到这，就可能创造多个实例
            singleton = new Singleton();
        }
        return singleton;
    }
}